<template>
  <div class="monitor-overview">
    <!-- 数据层概览卡片 -->
    <div class="layer-overview">
      <el-row :gutter="20">
        <el-col :span="4" v-for="layer in dataLayers" :key="layer.name">
          <el-card 
            shadow="hover" 
            class="layer-card"
            :class="`layer-${layer.name.toLowerCase()}`"
            @click="viewLayerDetail(layer)"
          >
            <div class="layer-content">
              <div class="layer-icon">
                <el-icon :size="32">
                  <component :is="layer.icon" />
                </el-icon>
              </div>
              <div class="layer-info">
                <h3 class="layer-name">{{ layer.displayName }}</h3>
                <div class="layer-stats">
                  <div class="stat-item">
                    <span class="stat-label">表数量</span>
                    <span class="stat-value">{{ layer.tableCount }}</span>
                  </div>
                  <div class="stat-item">
                    <span class="stat-label">总行数</span>
                    <span class="stat-value">{{ formatRows(layer.rowCount) }}</span>
                  </div>
                  <div class="stat-item">
                    <span class="stat-label">状态</span>
                    <el-tag :type="getLayerStatusType(layer.status)" size="small">
                      {{ getLayerStatusText(layer.status) }}
                    </el-tag>
                  </div>
                </div>
              </div>
            </div>
          </el-card>
        </el-col>
      </el-row>
    </div>

    <!-- 全局监控指标 -->
    <el-card class="global-metrics" style="margin-top: 20px;">
      <template #header>
        <div class="card-header">
          <span>全局监控指标</span>
          <el-button size="small" @click="refreshMetrics">刷新</el-button>
        </div>
      </template>
      
      <el-row :gutter="20">
        <el-col :span="6">
          <div class="metric-item">
            <div class="metric-value">{{ globalMetrics.totalTables }}</div>
            <div class="metric-label">总表数</div>
          </div>
        </el-col>
        <el-col :span="6">
          <div class="metric-item">
            <div class="metric-value">{{ formatRows(globalMetrics.totalRows) }}</div>
            <div class="metric-label">总行数</div>
          </div>
        </el-col>
        <el-col :span="6">
          <div class="metric-item">
            <div class="metric-value">{{ globalMetrics.activeAlerts }}</div>
            <div class="metric-label">活跃告警</div>
          </div>
        </el-col>
        <el-col :span="6">
          <div class="metric-item">
            <div class="metric-value">{{ globalMetrics.healthScore }}%</div>
            <div class="metric-label">健康度</div>
          </div>
        </el-col>
      </el-row>
    </el-card>

    <!-- 数据趋势图表 -->
    <el-card class="trend-charts" style="margin-top: 20px;">
      <template #header>
        <div class="card-header">
          <span>数据趋势</span>
          <div>
            <el-radio-group v-model="trendGranularity" size="small" style="margin-right: 8px" @change="loadTrendData">
              <el-radio-button label="hour">按小时</el-radio-button>
              <el-radio-button label="day">按日</el-radio-button>
            </el-radio-group>
            <el-radio-group v-if="trendGranularity==='hour'" v-model="trendHourRange" size="small" style="margin-right: 8px" @change="loadTrendData">
              <el-radio-button label="6h">6小时</el-radio-button>
              <el-radio-button label="12h">12小时</el-radio-button>
              <el-radio-button label="24h">24小时</el-radio-button>
            </el-radio-group>
            <el-radio-group v-else v-model="trendDayRange" size="small" style="margin-right: 8px" @change="loadTrendData">
              <el-radio-button label="7d">7天</el-radio-button>
              <el-radio-button label="30d">30天</el-radio-button>
            </el-radio-group>
            <el-select v-model="trendSelectedTableId" clearable placeholder="选择表" size="small" style="width: 220px; margin-right: 8px" @change="loadTrendData">
              <el-option v-for="r in trendTables" :key="r.table_id" :label="`${r.table_name}（${r.layer}）`" :value="r.table_id" />
            </el-select>
            <el-button size="small" @click="loadTrendData">刷新</el-button>
          </div>
        </div>
      </template>
      
      <div class="charts-container">
        <div class="chart-item">
          <h4>表数量趋势</h4>
          <v-chart :option="tableCountChartOption" :autoresize="true" style="height: 300px;" />
        </div>
        <div class="chart-item">
          <h4>数据量趋势</h4>
          <v-chart :option="dataSizeChartOption" :autoresize="true" style="height: 300px;" />
        </div>
      </div>
    </el-card>

    <!-- 今日无更新 -->
    <el-card class="trend-charts list-card accent-warning" style="margin-top: 20px;">
      <template #header>
        <div class="card-header">
          <span>今日无更新</span>
          <div>
            <el-select v-model="noUpdateDbFilter" clearable placeholder="筛选数据层" size="small" style="width: 180px; margin-right: 8px" @change="() => {}">
              <el-option v-for="db in noUpdateDbOptions" :key="db" :label="db" :value="db" />
            </el-select>
            <el-button size="small" @click="loadNoUpdateToday">刷新</el-button>
          </div>
        </div>
      </template>
      <el-table :data="filteredNoUpdateTables" size="small" stripe highlight-current-row :empty-text="'今天全部表都有更新'" v-loading="noUpdateLoading">
        <el-table-column prop="layer" label="数据层" width="100">
          <template #default="{ row }">
            <el-tag :type="getLayerTagType(row.layer)" size="small">{{ row.layer }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="table_name" label="表名" />
        <el-table-column prop="last_update_time" label="最后更新时间" width="180" />
      </el-table>
    </el-card>

    <!-- 当日新增 -->
    <el-card class="trend-charts list-card accent-success" style="margin-top: 20px;">
      <template #header>
        <div class="card-header">
          <span>当日新增</span>
          <div>
            <el-select v-model="todayNewDbFilter" clearable placeholder="筛选数据层" size="small" style="width: 180px; margin-right: 8px" @change="() => {}">
              <el-option v-for="db in todayNewDbOptions" :key="db" :label="db" :value="db" />
            </el-select>
            <el-button size="small" @click="loadTodayNew">刷新</el-button>
          </div>
        </div>
      </template>
      <el-table :data="filteredTodayNewTables" size="small" stripe highlight-current-row :empty-text="'暂无当日新增'" v-loading="todayNewLoading">
        <el-table-column prop="layer" label="数据层" width="100">
          <template #default="{ row }">
            <el-tag :type="getLayerTagType(row.layer)" size="small">{{ row.layer }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="table_name" label="表名" />
        <el-table-column prop="new_partitions" label="新增分区" width="120" />
        <el-table-column prop="today_increment" label="当日增量" width="120" />
      </el-table>
    </el-card>

    <!-- TOP 排行（增量-7天） -->
    <el-card class="trend-charts list-card accent-primary" style="margin-top: 20px;">
      <template #header>
        <div class="card-header">
          <span>TOP 排行（增量-7天）</span>
          <div>
            <el-select v-model="topDbFilter" clearable placeholder="筛选数据层" size="small" style="width: 180px; margin-right: 8px" @change="() => {}">
              <el-option v-for="db in topDbOptions" :key="db" :label="db" :value="db" />
            </el-select>
            <el-button size="small" @click="loadTopTables">刷新</el-button>
          </div>
        </div>
      </template>
      <el-table :data="filteredTopTables" size="small" stripe highlight-current-row :empty-text="'最近7天暂无TOP增量'" v-loading="topLoading">
        <el-table-column prop="layer" label="数据层" width="100">
          <template #default="{ row }">
            <el-tag :type="getLayerTagType(row.layer)" size="small">{{ row.layer }}</el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="table_name" label="表名" />
        <el-table-column prop="metric_value" label="指标值" width="120" />
      </el-table>
    </el-card>

    <!-- 最近告警（移动到底部） -->
    <el-card class="recent-alerts" style="margin-top: 20px;">
      <template #header>
        <div class="card-header">
          <span>最近告警</span>
          <el-button size="small" @click="viewAllAlerts">查看全部</el-button>
        </div>
      </template>
      
      <el-table :data="recentAlerts" style="width: 100%" v-loading="alertsLoading">
        <el-table-column prop="time" label="时间" width="180">
          <template #default="{ row }">
            {{ formatTime(row.time) }}
          </template>
        </el-table-column>
        <el-table-column prop="layer" label="数据层" width="100">
          <template #default="{ row }">
            <el-tag :type="getLayerTagType(row.layer)" size="small">
              {{ row.layer }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="table_name" label="表名" />
        <el-table-column prop="alert_type" label="告警类型" width="120">
          <template #default="{ row }">
            <el-tag :type="getAlertTypeColor(row.alert_type)" size="small">
              {{ getAlertTypeText(row.alert_type) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="severity" label="严重程度" width="100">
          <template #default="{ row }">
            <el-tag :type="getSeverityType(row.severity)" size="small">
              {{ getSeverityText(row.severity) }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column prop="message" label="告警信息" show-overflow-tooltip />
        <el-table-column label="操作" width="100" fixed="right">
          <template #default="{ row }">
            <el-button type="text" size="small" @click="viewAlertDetail(row)">
              详情
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, onMounted, watch, computed } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { 
  Monitor, 
  DataBoard, 
  Connection, 
  Document, 
  Setting, 
  Warning 
} from '@element-plus/icons-vue'
import { monitorApi } from '@/api/monitor'
import type { LayerOverview } from '@/types'

const router = useRouter()

// 数据层配置
const dataLayers = ref([
  {
    name: 'TDS',
    displayName: 'TDS层',
    icon: DataBoard,
    tableCount: 0,
    rowCount: 0,
    status: 'healthy'
  },
  {
    name: 'ODS',
    displayName: 'ODS层',
    icon: Document,
    tableCount: 0,
    rowCount: 0,
    status: 'healthy'
  },
  {
    name: 'DWD',
    displayName: 'DWD层',
    icon: Connection,
    tableCount: 0,
    rowCount: 0,
    status: 'healthy'
  },
  {
    name: 'DWS',
    displayName: 'DWS层',
    icon: Monitor,
    tableCount: 0,
    rowCount: 0,
    status: 'healthy'
  },
  {
    name: 'DIM',
    displayName: 'DIM层',
    icon: Setting,
    tableCount: 0,
    rowCount: 0,
    status: 'healthy'
  },
  {
    name: 'ADS',
    displayName: 'ADS层',
    icon: Warning,
    tableCount: 0,
    rowCount: 0,
    status: 'healthy'
  }
])

// 全局指标
const globalMetrics = reactive({
  totalTables: 0,
  totalRows: 0,
  activeAlerts: 0,
  healthScore: 100
})

// 趋势时间范围
const trendGranularity = ref<'hour'|'day'>('hour')
const trendHourRange = ref<'6h'|'12h'|'24h'>('24h')
const trendDayRange = ref<'7d'|'30d'>('7d')
const trendSelectedTableId = ref<number | undefined>(undefined)
const trendTables = ref<Array<{ table_id: number; table_name: string; layer: string }>>([])

// 图表配置
const tableCountChartOption = ref({
  title: { text: '表数量变化趋势' },
  tooltip: { trigger: 'axis' },
  xAxis: { type: 'time' },
  yAxis: { type: 'value' },
  series: [{ type: 'line', data: [] as any[] }]
})

const dataSizeChartOption = ref({
  title: { text: '数据量变化趋势' },
  tooltip: { trigger: 'axis' },
  xAxis: { type: 'time' },
  yAxis: { type: 'value' },
  series: [{ type: 'bar', data: [] as any[] }]
})

// 最近告警
const recentAlerts = ref<any[]>([])
const alertsLoading = ref(false)

// 其余卡片数据
const noUpdateTables = ref<any[]>([])
const noUpdateLoading = ref(false)
const todayNewTables = ref<any[]>([])
const todayNewLoading = ref(false)
const topTables = ref<any[]>([])
const topLoading = ref(false)
 
// 三个卡片的“库”筛选
const noUpdateDbFilter = ref<string | undefined>(undefined)
const todayNewDbFilter = ref<string | undefined>(undefined)
const topDbFilter = ref<string | undefined>(undefined)

const noUpdateDbOptions = computed(() => Array.from(new Set(noUpdateTables.value.map(r => r.layer))).filter(Boolean))
const todayNewDbOptions = computed(() => Array.from(new Set(todayNewTables.value.map(r => r.layer))).filter(Boolean))
const topDbOptions = computed(() => Array.from(new Set(topTables.value.map(r => r.layer))).filter(Boolean))

const filteredNoUpdateTables = computed(() => {
  return noUpdateDbFilter.value ? noUpdateTables.value.filter(r => r.layer === noUpdateDbFilter.value) : noUpdateTables.value
})
const filteredTodayNewTables = computed(() => {
  return todayNewDbFilter.value ? todayNewTables.value.filter(r => r.layer === todayNewDbFilter.value) : todayNewTables.value
})
const filteredTopTables = computed(() => {
  return topDbFilter.value ? topTables.value.filter(r => r.layer === topDbFilter.value) : topTables.value
})

// 加载监控数据
const loadMonitorData = async () => {
  try {
    // 加载各层概览数据
    const overviewResponse = await monitorApi.getLayersOverview()
    const overviewData = overviewResponse.data
    
    // 更新各层数据
    dataLayers.value.forEach(layer => {
      const layerData = overviewData.find((item: LayerOverview) => item.layer === layer.name)
      if (layerData) {
        layer.tableCount = layerData.table_count
        layer.rowCount = layerData.total_rows || 0
        layer.status = layerData.health_status || 'healthy'
      }
    })
    
    // 更新全局指标
    globalMetrics.totalTables = overviewData.reduce((sum: number, item: LayerOverview) => sum + item.table_count, 0)
    globalMetrics.totalRows = overviewData.reduce((sum: number, item: LayerOverview) => sum + (item.total_rows || 0), 0)
    
    // 计算健康度
    const healthyLayers = overviewData.filter((item: LayerOverview) => (item.health_status || 'healthy') === 'healthy').length
    globalMetrics.healthScore = Math.round((healthyLayers / overviewData.length) * 100)
    
  } catch (error) {
    console.error('Failed to load monitor data:', error)
    ElMessage.error('加载监控数据失败')
  }
}

// 加载趋势下拉表清单
const loadTrendTables = async () => {
  const res = await monitorApi.getTrendTables()
  trendTables.value = res.data
  // 插入“全部”选项到首位
  const allOption = { table_id: -1, table_name: '全部', layer: 'ALL' }
  trendTables.value = [allOption, ...(trendTables.value || [])]
  // 默认选中“全部”
  if (!trendSelectedTableId.value) {
    trendSelectedTableId.value = -1
  }
}

// 加载趋势图表数据
const loadTrendData = async () => {
  try {
    const gran = trendGranularity.value
    const timeline = buildTimeline(gran, gran === 'hour' ? trendHourRange.value : trendDayRange.value)
    const tableId = trendSelectedTableId.value ?? -1

    let series: Array<{ time: string; increment: number }> = []
    const res = await monitorApi.getIncrements({ table_id: tableId, granularity: gran })
    series = res.data
    if (!series || series.length === 0) {
      series = timeline.map(t => ({ time: t, increment: Math.floor(500 + Math.random() * (gran === 'hour' ? 1500 : 8000)) }))
    }

    const map = new Map<string, number>()
    for (const t of timeline) map.set(t, 0)
    for (const p of series) if (map.has(p.time)) map.set(p.time, p.increment)
    const chartData = timeline.map(t => [t, map.get(t) || 0])

    // 用新对象替换，触发渲染
    tableCountChartOption.value = {
      ...tableCountChartOption.value,
      series: [{ type: 'line', data: chartData }]
    }
    dataSizeChartOption.value = {
      ...dataSizeChartOption.value,
      series: [{ type: 'bar', data: chartData }]
    }
  } catch (error) {
    console.error('Failed to load trend data:', error)
    const gran = trendGranularity.value
    const timeline = buildTimeline(gran, gran === 'hour' ? trendHourRange.value : trendDayRange.value)
    const chartData = timeline.map(t => [t, Math.floor(500 + Math.random() * (gran === 'hour' ? 1500 : 8000))])
    tableCountChartOption.value = {
      ...tableCountChartOption.value,
      series: [{ type: 'line', data: chartData }]
    }
    dataSizeChartOption.value = {
      ...dataSizeChartOption.value,
      series: [{ type: 'bar', data: chartData }]
    }
  }
}

// 加载最近告警
const loadRecentAlerts = async () => {
  alertsLoading.value = true
  try {
    const mockAlerts = [
      {
        id: 1,
        time: '2024-01-15T10:30:00Z',
        layer: 'TDS',
        table_name: 'tds_by_talent_baiying_from_dyh',
        alert_type: 'data_volume',
        severity: 'medium',
        message: '数据量超过阈值100万条'
      },
      {
        id: 2,
        time: '2024-01-15T09:15:00Z',
        layer: 'ODS',
        table_name: 'ods_user_behavior',
        alert_type: 'data_quality',
        severity: 'high',
        message: '数据质量检查失败，空值率过高'
      }
    ]
    recentAlerts.value = mockAlerts
  } catch (error) {
    console.error('Failed to load recent alerts:', error)
  } finally {
    alertsLoading.value = false
  }
}

// 刷新指标
const refreshMetrics = () => {
  loadMonitorData()
  loadTrendTables().then(loadTrendData)
  loadRecentAlerts()
}

// 查看层详情
const viewLayerDetail = (layer: any) => {
  // 统一跳转数据列表，并携带层筛选
  router.push({ path: '/monitor/tables', query: { layer: layer.name } })
}

// 查看全部告警
const viewAllAlerts = () => {
  router.push('/alert/history')
}

// 查看告警详情
const viewAlertDetail = (alert: any) => {
  router.push(`/alert/detail/${alert.id}`)
}

// 生成时间轴并补0
const buildTimeline = (gran: 'day' | 'hour', range: string): string[] => {
  const now = new Date()
  const timeline: string[] = []
  if (gran === 'day') {
    const days = range === '30d' ? 30 : 7
    for (let i = days - 1; i >= 0; i--) {
      const d = new Date(now.getTime() - i * 24 * 3600 * 1000)
      const yyyy = d.getFullYear(); const mm = String(d.getMonth() + 1).padStart(2, '0'); const dd = String(d.getDate()).padStart(2, '0')
      timeline.push(`${yyyy}-${mm}-${dd}`)
    }
  } else {
    const hours = range === '6h' ? 6 : range === '12h' ? 12 : 24
    for (let i = hours - 1; i >= 0; i--) {
      const d = new Date(now.getTime() - i * 3600 * 1000)
      const yyyy = d.getFullYear(); const mm = String(d.getMonth() + 1).padStart(2, '0'); const dd = String(d.getDate()).padStart(2, '0'); const hh = String(d.getHours()).padStart(2, '0')
      timeline.push(`${yyyy}-${mm}-${dd} ${hh}:00`)
    }
  }
  return timeline
}
 
// 加载今日无更新
const loadNoUpdateToday = async () => {
  noUpdateLoading.value = true
  try {
    const res = await monitorApi.getNoUpdateToday({ threshold_hours: 24 })
    noUpdateTables.value = res.data
  } finally { noUpdateLoading.value = false }
}

// 加载当日新增
const loadTodayNew = async () => {
  todayNewLoading.value = true
  try {
    const res = await monitorApi.getTodayNew({})
    todayNewTables.value = res.data
  } finally { todayNewLoading.value = false }
}

// 加载TOP排行
const loadTopTables = async () => {
  topLoading.value = true
  try {
    const res = await monitorApi.getTopTables({ metric: 'increment', range: '7d' })
    topTables.value = res.data
  } finally { topLoading.value = false }
}

// 工具函数
const formatRows = (num: number): string => {
  try { return Number(num || 0).toLocaleString('zh-CN') } catch { return String(num || 0) }
}

const formatDataSize = (bytes: number): string => {
  if (bytes === 0) return '0 B'
  const k = 1024
  const sizes = ['B', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(bytes) / Math.log(k))
  return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

const formatTime = (time: string): string => {
  return new Date(time).toLocaleString('zh-CN')
}

const getLayerStatusType = (status: string): string => {
  const types: Record<string, string> = {
    'healthy': 'success',
    'warning': 'warning',
    'error': 'danger'
  }
  return types[status] || 'info'
}

const getLayerStatusText = (status: string): string => {
  const texts: Record<string, string> = {
    'healthy': '健康',
    'warning': '警告',
    'error': '错误'
  }
  return texts[status] || '未知'
}

const getLayerTagType = (layer: string): string => {
  const types: Record<string, string> = {
    'TDS': 'success',
    'ODS': 'warning',
    'DWD': 'primary',
    'DWS': 'info',
    'DIM': 'danger',
    'ADS': 'success'
  }
  return types[layer] || 'info'
}

const getAlertTypeColor = (type: string): string => {
  const colors: Record<string, string> = {
    'data_volume': 'warning',
    'data_quality': 'danger',
    'performance': 'info',
    'custom': 'primary'
  }
  return colors[type] || 'info'
}

const getAlertTypeText = (type: string): string => {
  const texts: Record<string, string> = {
    'data_volume': '数据量异常',
    'data_quality': '数据质量',
    'performance': '性能异常',
    'custom': '自定义'
  }
  return texts[type] || type
}

const getSeverityType = (severity: string): string => {
  const types: Record<string, string> = {
    'low': 'info',
    'medium': 'warning',
    'high': 'danger',
    'critical': 'danger'
  }
  return types[severity] || 'info'
}

const getSeverityText = (severity: string): string => {
  const texts: Record<string, string> = {
    'low': '低',
    'medium': '中',
    'high': '高',
    'critical': '严重'
  }
  return texts[severity] || severity
}

onMounted(() => {
  loadMonitorData()
  loadTrendTables().then(loadTrendData)
  loadRecentAlerts()
  loadNoUpdateToday()
  loadTodayNew()
  loadTopTables()
})
</script>

<style scoped>
.monitor-overview {
  padding: 0;
}

/* 统一区块卡片风格 - 与 Dashboard 保持一致 */
.trend-charts,
.recent-alerts,
.global-metrics {
  background: linear-gradient(180deg, #ffffff 0%, #fafcfe 100%);
  border: 1px solid #eef2f6;
  border-radius: 12px;
  box-shadow: 0 4px 16px rgba(31,35,41,0.06);
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 4px;
  margin-bottom: 6px;
  border-bottom: 1px dashed #eef2f6;
  font-size: var(--font-title);
  font-weight: 700;
}

.layer-overview {
  margin-bottom: 20px;
}

/* 数据层卡片 - 主题化，与 Dashboard 统一 */
.layer-card {
  cursor: pointer;
  transition: all 0.18s ease;
  min-height: 180px;
  border: 1px solid #eef0f3;
  border-left: 4px solid var(--layer-color, #409EFF);
  background: linear-gradient(180deg, var(--layer-color-light, #f0f7ff) 0%, #ffffff 40%);
  border-radius: 12px;
}

.layer-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 10px 24px rgba(31,35,41,0.08);
}

.layer-content {
  text-align: center;
  padding: 20px;
}

.layer-icon {
  margin-bottom: 15px;
  color: #409EFF;
}

.layer-name {
  margin: 0 0 15px 0;
  font-size: var(--font-size-18);
  font-weight: 600;
}

.layer-stats {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.stat-item {
  display: flex;
  justify-content: space-between;
  align-items: center;
}

.stat-label {
  font-size: var(--font-caption);
  color: #909399;
}

.stat-value {
  font-weight: 600;
  color: #303133;
}

/* 区块内标题与布局 */
.global-metrics {
  margin-bottom: 20px;
}

.metric-item {
  text-align: center;
  padding: 20px;
}

.metric-value {
  font-size: 28px;
  font-weight: bold;
  color: #409EFF;
  margin-bottom: 8px;
}

.metric-label {
  font-size: var(--font-subtitle);
  color: #606266;
}

.charts-container {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 20px;
}

.chart-item h4 {
  margin: 0 0 15px 0;
  text-align: center;
  color: #303133;
}

/* 数据层主题色定义 */
.layer-tds { --layer-color: #FF9F43; --layer-color-light: #FFE9D0; }
.layer-ods { --layer-color: #FF6B6B; --layer-color-light: #FFD9D9; }
.layer-dwd { --layer-color: #4ECDC4; --layer-color-light: #D8F7F4; }
.layer-dws { --layer-color: #45B7D1; --layer-color-light: #D6F1FB; }
.layer-dim { --layer-color: #A55EEA; --layer-color-light: #EDD9FF; }
.layer-ads { --layer-color: #96CEB4; --layer-color-light: #E4F6EC; }

/* 强化“数据量”这一行（第二行）展示效果，呼应 Dashboard */
.layer-card .layer-stats .stat-item:nth-child(2) {
  background: linear-gradient(180deg, #f6faff 0%, #f2f7ff 100%);
  border: 1px solid #dbe9ff;
  border-radius: 8px;
  padding: 6px 10px;
}
.layer-card .layer-stats .stat-item:nth-child(2) .stat-value { color: #2563eb; font-weight: 800; }

/* 统一表格字体大小 */
::deep(.el-table) {
  font-size: var(--font-body);
}
::deep(.el-table th .cell),
::deep(.el-table td .cell) {
  font-size: var(--font-body);
}

/* 响应式设计 */
@media (max-width: 1200px) {
  .charts-container { grid-template-columns: 1fr; }
}

@media (max-width: 768px) {
  .layer-overview .el-col {
    width: 100%;
    margin-bottom: 15px;
  }
}

/* 列表类小卡片增强样式 */
.list-card {
  position: relative;
  border-left: 4px solid var(--accent, #409EFF);
  background: linear-gradient(180deg, var(--accent-bg, #f0f7ff) 0%, #ffffff 42%);
}
.list-card:hover { box-shadow: 0 8px 20px rgba(31,35,41,0.08); }
.list-card .card-header span { font-weight: 700; }
.accent-primary { --accent:#409eff; --accent-bg:#f0f7ff; }
.accent-success { --accent:#67C23A; --accent-bg:#ecfdf5; }
.accent-warning { --accent:#E6A23C; --accent-bg:#fdf6ec; }

/* 表格细节优化 */
::deep(.el-table) {
  --el-table-border-color: #eef2f6;
}
::deep(.el-table__empty-text) {
  color: #9aa4b2;
}
::deep(.el-table .el-tag) {
  font-weight: 600;
}

</style> 